package com.mrjoew.weekend.services.impl.shop;

import com.google.common.collect.Maps;
import com.mrjoew.weekend.entities.po.shop.CarPO;
import com.mrjoew.weekend.entities.vo.shop.CarVO;
import com.mrjoew.weekend.repositories.shop.CarRepository;
import com.mrjoew.weekend.services.shop.CarService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author Christopher Jones
 * @ClassName CarServiceImpl
 * @explain
 * @date 2020/11/6 0006 22:58
 */
@Service
public class CarServiceImpl implements CarService {

    private final RedisTemplate<Object, Object> redisTemplate;

    private final CarRepository carRepository;

    public CarServiceImpl(CarRepository carRepository, RedisTemplate<Object, Object> redisTemplate) {
        this.carRepository = carRepository;
        this.redisTemplate = redisTemplate;
    }

    @Override
    public Page<CarVO> list(Pageable pageable, String id) {
        // redis 分页
        long start = pageable.getPageNumber() * pageable.getPageSize();
        long end = start + pageable.getPageSize();

        return Optional.ofNullable(cars(id)).map(v ->
                (Page<CarVO>) new PageImpl<>(
                        v.entrySet().stream().map(kv -> new CarVO(kv.getKey(), kv.getValue())).collect(Collectors.toList()),
                        pageable,
                        v.size())
        ).orElse(Page.empty());
    }

    @Override
    public void del(Integer goodsId, String id) {
        Map<Integer, Integer> cars = cars(id);

        if (cars.size() > 0) {
            cars.remove(goodsId);
            redisTemplate.opsForValue().set(CarPO.CAR + id, cars);
        }
    }

    @Override
    public void put(Integer goodsId, Integer number, String id) {
        Map<Integer, Integer> cars = cars(id);

        // 购物车里如果没有直接添加, 否则累加
        cars.put(goodsId, Optional.ofNullable(cars.get(goodsId)).map(n -> n + number).orElse(number));

        redisTemplate.opsForValue().set(CarPO.CAR + id, cars);
    }

    private Map<Integer, Integer> cars(String id) {
        // 获取该用户/或session的购物车
        Map<Integer, Integer> cars = Optional.ofNullable(redisTemplate.opsForValue().get(CarPO.CAR + id))
                .map(v -> (Map<Integer, Integer>) v)
                .orElse(Maps.newHashMap());

        return cars;
    }
}
